home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2000 February / Macworld (2000-02).dmg / Cool Extras! / WallBall Screen Saver / WallBall.dxr / 00025_Random Movement and Rotation.ls < prev    next >
Encoding:
Text File  |  1999-11-11  |  7.5 KB  |  204 lines

  1. property pSprite, pCenterOffset, pLimits, pLimitsOrigin, pPath, pMovePeriod, pMoveStart, pMoveEnd, pRotate, pRotateStart, pRotatePeriod, pRotateEnd, pLimitsLeft, pLimitsRight, pLimitsTop, pLimitsBottom, pSpeed, pRotationSpeed, pLoopiness, pWackiness
  2.  
  3. on getBehaviorDescription
  4.   vDesc = "RANDOM MOVEMENT & ROTATION" & RETURN & RETURN
  5.   vDesc = vDesc & "Sprite will move randomly within defined area, spinning"
  6.   vDesc = vDesc && "wildly if so desired. Author can control both the speed of"
  7.   vDesc = vDesc && "the movement and speed of rotation, as well as how radically"
  8.   vDesc = vDesc && "the movement and rotation vary. Default movement limit"
  9.   vDesc = vDesc && "is the stage area." & RETURN & RETURN
  10.   vDesc = vDesc & "PERMITTED MEMBER TYPES:" & RETURN & mPermittedMemberTypes()
  11.   vDesc = vDesc & RETURN & RETURN & "PARAMETERS:" & RETURN
  12.   vDesc = vDesc & " - Horizontal and vertical coordinates for movement limits"
  13.   vDesc = vDesc & RETURN & " - Average speed in pixels/second" & RETURN
  14.   vDesc = vDesc & " - Loopiness modifies how close the sprite's path is to"
  15.   vDesc = vDesc && "a straight line." & RETURN
  16.   vDesc = vDesc & " - Rotation speed determines how fast sprite rotates;"
  17.   vDesc = vDesc && "1000 = 360 degrees/second" & RETURN
  18.   vDesc = vDesc & " - Wackiness controls how much the rotation of the"
  19.   vDesc = vDesc & "sprite may vary before changing direction."
  20.   return vDesc
  21. end
  22.  
  23. on getBehaviorTooltip me
  24.   vTip = "Animate a sprite along a random path" & RETURN
  25.   vTip = vTip & "and determine its motion and speed" & RETURN
  26.   vTip = vTip & "while it is animating."
  27.   return vTip
  28. end
  29.  
  30. on beginSprite me
  31.   mInitialize(me)
  32. end
  33.  
  34. on prepareFrame me
  35.   mUpdate(me)
  36. end
  37.  
  38. on mInitialize me
  39.   pSprite = sprite(me.spriteNum)
  40.   vMember = pSprite.member
  41.   if not getPos(mPermittedMemberTypes(), vMember.type) then
  42.   end if
  43.   case vMember.type of
  44.     #animgif, #flash, #quickTimeMedia, #digitalVideo, #vectorShape:
  45.       if vMember.directToStage then
  46.       end if
  47.   end case
  48.   if pRotationSpeed > 0 then
  49.     case vMember.type of
  50.       #field, #picture:
  51.         pRotationSpeed = 0
  52.     end case
  53.   end if
  54.   vRect = pSprite.rect
  55.   vHalfHeight = vRect.height / 2
  56.   vHalfWidth = vRect.width / 2
  57.   vMaxDimension = max(vHalfHeight, vHalfWidth)
  58.   vFarCorner = max(mVectorLength(pSprite.loc - point(vRect.left, vRect.top)), mVectorLength(pSprite.loc - point(vRect.right, vRect.top)), mVectorLength(pSprite.loc - point(vRect.left, vRect.bottom)), mVectorLength(pSprite.loc - point(vRect.right, vRect.bottom)))
  59.   vCenter = point(vHalfWidth, vHalfHeight) + point(vRect.left, vRect.top)
  60.   pCenterOffset = vCenter - pSprite.loc
  61.   pLimits = rect(pLimitsLeft, pLimitsTop, pLimitsRight, pLimitsBottom)
  62.   pLimits = pLimits + rect(vFarCorner, vFarCorner, -vFarCorner, -vFarCorner)
  63.   if (pLimits.width < vRect.width) or (pLimits.height < vRect.height) then
  64.   end if
  65.   pLimitsOrigin = point(pLimits.left, pLimits.top)
  66.   mNewPath(me)
  67.   mNewRotation(me)
  68. end
  69.  
  70. on mUpdate me
  71.   vTime = the milliSeconds
  72.   mMove(me, vTime)
  73.   mRotate(me, vTime)
  74. end
  75.  
  76. on mMove me, vTime
  77.   if pSpeed then
  78.     if vTime < pMoveEnd then
  79.       vElapsed = vTime - pMoveStart
  80.       if vElapsed > 0 then
  81.         vT1 = float(vElapsed) / pMovePeriod
  82.         vT2 = vT1 * vT1
  83.         vT3 = vT2 * vT1
  84.         vNewPosition = pPath.p0
  85.         vModPoint = pPath.dc * vT1
  86.         vNewPosition = vNewPosition + vModPoint
  87.         vModPoint = pPath.db * vT2
  88.         vNewPosition = vNewPosition + vModPoint
  89.         vModPoint = pPath.da * vT3
  90.         vNewPosition = vNewPosition + vModPoint
  91.         pSprite.loc = vNewPosition
  92.       end if
  93.     else
  94.       pSprite.loc = pPath.p3
  95.       mNewPath(me)
  96.     end if
  97.   end if
  98. end
  99.  
  100. on mRotate me, vTime
  101.   if pRotationSpeed then
  102.     if vTime < pRotateEnd then
  103.       vElapsed = vTime - pRotateStart
  104.       if vElapsed > 0 then
  105.         vRotation = pRotate.start + (pRotate.diff * vElapsed / pRotatePeriod)
  106.         pSprite.rotation = vRotation
  107.       end if
  108.     else
  109.       pSprite.rotation = pRotate.end
  110.       mNewRotation(me)
  111.     end if
  112.   end if
  113. end
  114.  
  115. on mNewPath me
  116.   if voidp(pPath) then
  117.     pPath = [#p0: pSprite.loc, #p1: pSprite.loc, #p2: pSprite.loc, #p3: pSprite.loc]
  118.   end if
  119.   if pSpeed then
  120.     vDest = point(random(pLimits.width), random(pLimits.height)) + pLimitsOrigin
  121.     vP0 = pPath.p3
  122.     vVector = vDest - vP0
  123.     vVectorLen = mVectorLength(vVector)
  124.     vLoopiness = vVectorLen * pLoopiness / 25
  125.     vP1 = mRestrain(vP0 + (pPath.p3 - pPath.p2), pLimits)
  126.     if vLoopiness then
  127.       vRandomPoint = point(mRandomSign() * random(vLoopiness), mRandomSign() * random(vLoopiness))
  128.     else
  129.       vRandomPoint = point(0, 0)
  130.     end if
  131.     vP2 = mRestrain(vP0 + (vVector * 2 / 3) + vRandomPoint, pLimits)
  132.     pPath = [#p0: vP0, #p1: vP1, #p2: vP2, #p3: vDest]
  133.     setaProp(pPath, #dc, 3 * (pPath.p1 - pPath.p0))
  134.     setaProp(pPath, #db, (3 * (pPath.p2 - pPath.p1)) - pPath.dc)
  135.     setaProp(pPath, #da, pPath.p3 - pPath.p0 - pPath.dc - pPath.db)
  136.     vDistance = mVectorLength(pPath.p0 - pPath.p1) + mVectorLength(pPath.p1 - pPath.p2) + mVectorLength(pPath.p2 - pPath.p3)
  137.     pMovePeriod = vDistance * 1000 / pSpeed
  138.     pMoveStart = the milliSeconds
  139.     pMoveEnd = pMoveStart + pMovePeriod
  140.   end if
  141. end
  142.  
  143. on mNewRotation me
  144.   if voidp(pRotate) then
  145.     pRotate = [#start: 0, #end: 0, #diff: 0]
  146.   end if
  147.   if pRotationSpeed then
  148.     vRotation = pSprite.rotation
  149.     if pRotate.diff < 0 then
  150.       vOffset = random(pWackiness)
  151.     else
  152.       vOffset = -random(pWackiness)
  153.     end if
  154.     vTargetRotation = vRotation + vOffset
  155.     pRotateStart = the milliSeconds
  156.     pRotatePeriod = abs(vOffset) * 1000 / pRotationSpeed * 1000 / 360
  157.     pRotateEnd = pRotateStart + pRotatePeriod
  158.     pRotate = [#start: vRotation, #end: vTargetRotation, #diff: vOffset]
  159.   end if
  160. end
  161.  
  162. on mVectorLength vVector
  163.   vSquare = (vVector.locH * vVector.locH) + (vVector.locV * vVector.locV)
  164.   return sqrt(vSquare)
  165. end
  166.  
  167. on mRandomSign
  168.   return (random(2) * 2) - 3
  169. end
  170.  
  171. on mRestrain vPoint, vRect
  172.   vPoint.locH = max(vRect.left, min(vRect.right, vPoint.locH))
  173.   vPoint.locV = max(vRect.top, min(vRect.bottom, vPoint.locV))
  174.   return vPoint
  175. end
  176.  
  177. on getPropertyDescriptionList me
  178.   if not (the currentSpriteNum) then
  179.     exit
  180.   end if
  181.   vRect = (the stage).rect
  182.   vMemberType = sprite(the currentSpriteNum).member.type
  183.   case vMemberType of
  184.     #text, #picture:
  185.       vRotateSpeed = 0
  186.     otherwise:
  187.       vRotateSpeed = 100
  188.   end case
  189.   vPDList = [:]
  190.   setaProp(vPDList, #pLimitsLeft, [#comment: "Limit of movement (left)", #format: #integer, #default: 0, #range: [#min: 0, #max: vRect.width]])
  191.   setaProp(vPDList, #pLimitsTop, [#comment: "Limit of movement (top)", #format: #integer, #default: 0, #range: [#min: 0, #max: vRect.height]])
  192.   setaProp(vPDList, #pLimitsRight, [#comment: "Limit of movement (right)", #format: #integer, #default: vRect.width, #range: [#min: 0, #max: vRect.width]])
  193.   setaProp(vPDList, #pLimitsBottom, [#comment: "Limit of movement (bottom)", #format: #integer, #default: vRect.height, #range: [#min: 0, #max: (the stage).rect.height]])
  194.   setaProp(vPDList, #pSpeed, [#comment: "Speed of movement", #format: #integer, #default: 100, #range: [#min: 0, #max: 1000]])
  195.   setaProp(vPDList, #pLoopiness, [#comment: "Loopiness", #format: #integer, #default: 10, #range: [#min: 0, #max: 25]])
  196.   setaProp(vPDList, #pRotationSpeed, [#comment: "Speed of rotation", #format: #integer, #default: vRotateSpeed, #range: [#min: 0, #max: 1000]])
  197.   setaProp(vPDList, #pWackiness, [#comment: "Wackiness", #format: #integer, #default: 120, #range: [#min: 0, #max: 360]])
  198.   return vPDList
  199. end
  200.  
  201. on mPermittedMemberTypes me
  202.   return [#bitmap, #flash, #picture, #field, #text, #vectorShape, #animgif]
  203. end
  204.